package com.zhengbing.tj.design.singleton;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

/**
 * 单例模式破解测试类
 * 演示通过反射、序列化等方式破解各种单例实现
 * @author zhengbing
 * @date 2025-07-25
 */
public class SingletonCrackTest {
    public static void main(String[] args) {
        // 测试破解饿汉式单例
        crackEagerSingleton();

        // 测试破解懒汉式单例
        crackLazySingleton();

        // 测试破解线程安全懒汉式单例
        crackSynchronizedLazySingleton();

        // 测试破解双重检查锁定单例
    crackDoubleCheckedLockingSingleton();

    // 测试破解枚举单例
    crackEnumSingleton();
    }

    /**
     * 破解饿汉式单例
     */
    private static void crackEagerSingleton() {
        System.out.println("=== 破解饿汉式单例 ===");
        EagerSingleton instance1 = EagerSingleton.getInstance();
        EagerSingleton instance2 = null;

        try {
            // 使用反射获取构造器
            Constructor<EagerSingleton> constructor = EagerSingleton.class.getDeclaredConstructor();
            constructor.setAccessible(true); // 设置私有构造器可访问
            instance2 = constructor.newInstance(); // 创建新实例

            System.out.println("实例1: " + instance1);
            System.out.println("实例2: " + instance2);
            System.out.println("破解结果: " + (instance1 != instance2 ? "成功" : "失败"));
        } catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException e) {
            e.printStackTrace();
        }
        System.out.println();
    }

    /**
     * 破解懒汉式单例
     */
    private static void crackLazySingleton() {
        System.out.println("=== 破解懒汉式单例 ===");
        LazySingleton instance1 = LazySingleton.getInstance();
        LazySingleton instance2 = null;

        try {
            Constructor<LazySingleton> constructor = LazySingleton.class.getDeclaredConstructor();
            constructor.setAccessible(true);
            instance2 = constructor.newInstance();

            System.out.println("实例1: " + instance1);
            System.out.println("实例2: " + instance2);
            System.out.println("破解结果: " + (instance1 != instance2 ? "成功" : "失败"));
        } catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException e) {
            e.printStackTrace();
        }
        System.out.println();
    }

    /**
     * 破解线程安全懒汉式单例
     */
    private static void crackSynchronizedLazySingleton() {
        System.out.println("=== 破解线程安全懒汉式单例 ===");
        SynchronizedLazySingleton instance1 = SynchronizedLazySingleton.getInstance();
        SynchronizedLazySingleton instance2 = null;

        try {
            Constructor<SynchronizedLazySingleton> constructor = SynchronizedLazySingleton.class.getDeclaredConstructor();
            constructor.setAccessible(true);
            instance2 = constructor.newInstance();

            System.out.println("实例1: " + instance1);
            System.out.println("实例2: " + instance2);
            System.out.println("破解结果: " + (instance1 != instance2 ? "成功" : "失败"));
        } catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException e) {
            e.printStackTrace();
        }
        System.out.println();
    }

    /**
     * 破解双重检查锁定单例
     */
    private static void crackEnumSingleton() {
        System.out.println("=== 破解枚举单例 ===");
        EnumSingleton instance1 = EnumSingleton.INSTANCE;
        EnumSingleton instance2 = null;

        try {
            // 使用反射获取构造器
            Constructor<EnumSingleton> constructor = EnumSingleton.class.getDeclaredConstructor();
            constructor.setAccessible(true); // 设置私有构造器可访问
            instance2 = constructor.newInstance(); // 创建新实例

            System.out.println("实例1: " + instance1);
            System.out.println("实例2: " + instance2);
            System.out.println("破解结果: " + (instance1 != instance2 ? "成功" : "失败"));
        } catch (NoSuchMethodException e) {
            System.out.println("破解失败: 枚举类没有可访问的构造器");
        } catch (IllegalAccessException | InstantiationException | InvocationTargetException e) {
            e.printStackTrace();
            System.out.println("破解失败: " + e.getMessage());
        }
        System.out.println();
    }

    private static void crackDoubleCheckedLockingSingleton() {
        System.out.println("=== 破解双重检查锁定单例 ===");
        DoubleCheckedLockingSingleton instance1 = DoubleCheckedLockingSingleton.getInstance();
        DoubleCheckedLockingSingleton instance2 = null;

        try {
            Constructor<DoubleCheckedLockingSingleton> constructor = DoubleCheckedLockingSingleton.class.getDeclaredConstructor();
            constructor.setAccessible(true);
            instance2 = constructor.newInstance();

            System.out.println("实例1: " + instance1);
            System.out.println("实例2: " + instance2);
            System.out.println("破解结果: " + (instance1 != instance2 ? "成功" : "失败"));
        } catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException e) {
            e.printStackTrace();
        }
        System.out.println();
    }
}